// FlatBoll 指标：基于布林带的平坦检测指标
// 参考 TradingView: Flat Detect By Bollinger Bands

// 计算 ATR
function calculateATR(dataList, length, smoothing = 'RMA') {
  if (dataList.length < length + 1) return []
  
  const results = []
  let atr = null
  let prevClose = dataList[0]?.close ?? 0
  
  for (let i = 0; i < dataList.length; i++) {
    const candle = dataList[i]
    const tr = Math.max(
      candle.high - candle.low,
      Math.abs(candle.high - prevClose),
      Math.abs(candle.low - prevClose)
    )
    prevClose = candle.close
    
    if (i === 0) {
      results.push(null)
      continue
    }
    
    // 根据平滑方法计算ATR
    if (smoothing === 'RMA') {
      // RMA (Running Moving Average)
      const alpha = 1 / length
      atr = atr == null ? tr : (alpha * tr + (1 - alpha) * atr)
    } else if (smoothing === 'SMA') {
      // SMA
      if (i < length) {
        const sum = dataList.slice(Math.max(0, i - length + 1), i + 1).reduce((acc, c) => {
          const prevC = dataList[dataList.indexOf(c) - 1]
          if (!prevC) return acc
          const tr = Math.max(
            c.high - c.low,
            Math.abs(c.high - prevC.close),
            Math.abs(c.low - prevC.close)
          )
          return acc + tr
        }, 0)
        atr = sum / (i + 1)
      } else {
        const prevC = dataList[i - length]
        const prevTr = Math.max(
          prevC.high - prevC.low,
          Math.abs(prevC.high - (dataList[i - length - 1]?.close ?? prevC.close)),
          Math.abs(prevC.low - (dataList[i - length - 1]?.close ?? prevC.close))
        )
        atr = atr + (tr - prevTr) / length
      }
    } else if (smoothing === 'EMA') {
      // EMA
      const alpha = 2 / (length + 1)
      atr = atr == null ? tr : (alpha * tr + (1 - alpha) * atr)
    } else if (smoothing === 'WMA') {
      // WMA (Weighted Moving Average)
      if (i < length) {
        const weights = []
        let sum = 0
        let weightSum = 0
        for (let j = 0; j <= i; j++) {
          const prevC = dataList[j - 1]
          if (!prevC && j > 0) continue
          const tr = j === 0 ? (dataList[j].high - dataList[j].low) : Math.max(
            dataList[j].high - dataList[j].low,
            Math.abs(dataList[j].high - prevC.close),
            Math.abs(dataList[j].low - prevC.close)
          )
          const weight = j + 1
          weights.push({ tr, weight })
          sum += tr * weight
          weightSum += weight
        }
        atr = sum / weightSum
      } else {
        // 简化处理：使用RMA代替复杂WMA计算
        const alpha = 1 / length
        atr = atr == null ? tr : (alpha * tr + (1 - alpha) * atr)
      }
    }
    
    results.push(atr)
  }
  
  return results
}

// 计算布林带和FlatBoll指标
function calculateFlatBoll(dataList, params) {
  const {
    bbLength = 20,
    bbSrc = 'close',
    bbMult = 2.0,
    thresholdType = 'Ticks',
    thresholdWidth = 0.055,
    thresholdWidthPercent = 1.0,
    addATRFilter = false,
    atrLength = 14,
    atrSmoothing = 'RMA',
    atrThreshold = 25
  } = params
  
  if (dataList.length < bbLength) return []
  
  const results = []
  let sum = 0
  const closes = []
  
  // 计算ATR（如果需要）
  const atrValues = addATRFilter ? calculateATR(dataList, atrLength, atrSmoothing) : []
  
  for (let i = 0; i < dataList.length; i++) {
    const candle = dataList[i]
    const src = bbSrc === 'close' ? candle.close : 
                bbSrc === 'open' ? candle.open :
                bbSrc === 'high' ? candle.high :
                bbSrc === 'low' ? candle.low : candle.close
    
    closes.push(src)
    sum += src
    
    if (i < bbLength - 1) {
      results.push({
        basis: null,
        upper: null,
        lower: null,
        bbw: null,
        bbwPercent: null,
        isFlat: null,
        color: null
      })
      continue
    }
    
    // 计算布林带中轨（SMA）
    const basis = sum / bbLength
    
    // 计算标准差
    let sumSquaredDiff = 0
    for (let j = i - bbLength + 1; j <= i; j++) {
      const diff = closes[j] - basis
      sumSquaredDiff += diff * diff
    }
    const stdDev = Math.sqrt(sumSquaredDiff / bbLength)
    
    // 计算上轨和下轨
    const bbDev = bbMult * stdDev
    const upper = basis + bbDev
    const lower = basis - bbDev
    
    // 计算布林带宽度
    const bbw = (upper - lower) / basis
    const bbwPercent = (upper - lower) / upper * 100
    
    // ATR过滤
    const atrSignal = addATRFilter ? (atrValues[i] ?? 0) : 0
    const atrNoTrade = addATRFilter ? (atrSignal <= atrThreshold) : false
    const atrGoTrade = !atrNoTrade
    
    // 判断是否平坦
    let isFlat = false
    if (thresholdType === '%') {
      isFlat = (bbwPercent > thresholdWidthPercent) && atrGoTrade
    } else {
      isFlat = (bbw > thresholdWidth) && atrGoTrade
    }
    
    // 确定颜色（绿色=平坦，红色=不平坦）
    const color = isFlat ? '#00ff00' : '#ff0000' // lime : red
    
    results.push({
      basis,
      upper,
      lower,
      bbw,
      bbwPercent,
      isFlat,
      color,
      atrSignal: addATRFilter ? atrSignal : null
    })
    
    // 滑动窗口：移除最旧的值
    sum -= closes[i - bbLength + 1]
  }
  
  return results
}

// 导出指标定义
const flatBollIndicator = {
  name: 'FlatBoll',
  shortName: 'FlatBoll',
  calcParams: [20, 2.0], // [bbLength, bbMult]
  figures: [
    // 中轨（橙色）
    { 
      key: 'basis', 
      title: 'Basis: ', 
      type: 'line',
      styles: () => ({
        color: '#FF6D00',
        size: 1
      })
    },
    // 上轨（根据isFlat状态改变颜色）
    {
      key: 'upper',
      title: 'Upper: ',
      type: 'line',
      styles: (data, indicator, defaultStyles) => {
        const isFlat = data?.current?.isFlat ?? false
        return {
          color: isFlat ? '#00ff00' : '#ff0000',
          size: 1
        }
      }
    },
    // 下轨（根据isFlat状态改变颜色）
    {
      key: 'lower',
      title: 'Lower: ',
      type: 'line',
      styles: (data, indicator, defaultStyles) => {
        const isFlat = data?.current?.isFlat ?? false
        return {
          color: isFlat ? '#00ff00' : '#ff0000',
          size: 1
        }
      }
    }
  ],
  calc: (dataList, indicatorInstance) => {
    const [bbLength, bbMult] = indicatorInstance.calcParams
    
    return calculateFlatBoll(dataList, {
      bbLength,
      bbSrc: 'close',
      bbMult,
      thresholdType: 'Ticks',
      thresholdWidth: 0.055,
      thresholdWidthPercent: 1.0,
      addATRFilter: false,
      atrLength: 14,
      atrSmoothing: 'RMA',
      atrThreshold: 25
    })
  }
}

export default flatBollIndicator
export { calculateFlatBoll }

